/**
 * 项目名称（软件名称）：忠旺机械物资管理系统(mms)
 * 研发设计单位：忠旺机械设备制造有限公司机械设计院智能控制设计科设计与研发。
 * 版权所有：忠旺机械设备制造有限公司
 * 注：本项目的一切技术专利，使用规范归解释权由忠旺机械设备制造有限公司所有。
 * 软件版本：Ver 1.0.0
 * 文件路径：com.zhongwang.mms.module.purchase.service
 * 创建时间：2020年04月07日 19时08分
 **/
package com.zhongwang.mms.module.purchase.service;

import com.zhongwang.mms.base.BaseService;
import com.zhongwang.mms.common.JsonResult;
import com.zhongwang.mms.gen.entity.PInventory;
import com.zhongwang.mms.module.basic.dao.TWarehouseInfoDao;
import com.zhongwang.mms.module.purchase.dao.PurAnnexDao;
import com.zhongwang.mms.module.purchase.dao.PurPInventoryDao;
import com.zhongwang.mms.module.purchase.dao.PurPInventoryMaterielInfoDao;
import com.zhongwang.mms.module.purchase.model.PAnnexModel;
import com.zhongwang.mms.module.purchase.model.PInventoryMaterielInfoModel;
import com.zhongwang.mms.module.purchase.model.PInventoryModel;
import com.zhongwang.mms.module.purchase.model.PInventorySavePartialModel;
import com.zhongwang.mms.module.system.log.LogService;
import com.zhongwang.mms.util.LogFormatUtil;
import com.zhongwang.mms.util.ShiroUtils;
import com.zhongwang.mms.util.StringUtils;
import com.zhongwang.mms.util.XYHFileUtils;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ClassName： PInventoryInfoEditService
 * @Description：
 * @Author： 徐一贺
 * @Date： 2020/4/7 19:08
 * @Version： V1.0
 **/
@Log4j2
@Service
public class PInventoryInfoEditService extends BaseService {

    @Autowired
    private PurPInventoryDao purPInventoryDao;

    @Autowired
    private LogService logService;

    @Autowired
    private PurAnnexDao purAnnexDao;

    @Autowired
    private PurPInventoryMaterielInfoDao purPInventoryMaterielInfoDao;

    @Autowired
    private TWarehouseInfoDao tWarehouseInfoDao;

    /**
     * @FunctionName: upload
     * @Description: 文件上传
     * @DesignIdea: 上传文件，并根据客户端传递来的外购件库存主键和客户端IP生成附件列表。
     * @Author: 徐一贺
     * @CreateDate: 2020/5/16 15:42
     * @Phone: 18241927380
     * @Param: [file, anxItyId, anxUploadIp]上传的文件、外购件库存主键，客户端IP地址
     * @Return: com.zhongwang.mms.common.JsonResult 上传结果
     * @Throw: 无异常抛出
     * @Version: v 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public String upload(MultipartFile file, String anxItyId, String anxUploadIp) {
        if (file.isEmpty()) {
            return "请选择文件!";
        }
        PAnnexModel pAnnexModel = null;
        String fileType = null;
        Double fileSize = Double.valueOf(file.getSize()) / 1024 / 1024;
        if (fileSize > 10) {
            return "文件过大超过10MB，请选择处理文件后上传！";
        }
        try {
            fileType = XYHFileUtils.getFileTypeByStream(file.getBytes());
            if (fileType == null) {
                fileType = file.getContentType().substring(file.getContentType().indexOf("/") + 1);
            }
            if (fileType.equals("exe")) {
                return "不支持上传exe格式文件！";
            }
        } catch (IOException e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }
        String path = null;
        try {
            path = XYHFileUtils.upload(file);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }
        if (path != null) {
            pAnnexModel = new PAnnexModel();
            pAnnexModel.setAnxItyId(Integer.valueOf(anxItyId));
            pAnnexModel.setAnxFileType(fileType);
            pAnnexModel.setAnxFileName(file.getOriginalFilename());
            pAnnexModel.setAnxFilePath(path);
            pAnnexModel.setAnxUploadUid(ShiroUtils.getUserId());
            pAnnexModel.setAnxUploadDate(new Date());
            if (Double.valueOf(file.getSize()) < 1024) {
                pAnnexModel.setAnxFileSize(Double.valueOf(file.getSize()));
                pAnnexModel.setAnxFileSizeUnit("B");
            } else if (Double.valueOf(file.getSize()) < (1024 * 1024)) {
                pAnnexModel.setAnxFileSize(Double.valueOf(new DecimalFormat("#.00").format(Double.valueOf(file.getSize()) / 1024)));
                pAnnexModel.setAnxFileSizeUnit("KB");
            } else if (Double.valueOf(file.getSize()) >= (1024 * 1024)) {
                pAnnexModel.setAnxFileSize(Double.valueOf(new DecimalFormat("#.00").format(Double.valueOf(file.getSize()) / 1024 / 1024)));
                pAnnexModel.setAnxFileSizeUnit("MB");
            }
            pAnnexModel.setAxnFileStatus(1);
            pAnnexModel.setAnxUploadIp(anxUploadIp);
            pAnnexModel.setAnxDownloadCount(0);
            purAnnexDao.insertPAnnexSelective(pAnnexModel);
            PInventoryModel pInventory = purPInventoryDao.getInventoryByPrimaryKey(pAnnexModel.getAnxItyId());
            if (pInventory.getItyAnnexFlag() == null || pInventory.getItyAnnexFlag().equals(0)) {
                PInventory changePInventoryAnnexFlagModel = new PInventory();
                changePInventoryAnnexFlagModel.setItyId(pAnnexModel.getAnxItyId());
                changePInventoryAnnexFlagModel.setItyAnnexFlag(1);
                purPInventoryDao.updateByPrimaryKeySelective(changePInventoryAnnexFlagModel);
            }
            logService.saveLog("【外购件】库存信息编辑", "被上传文件的物料描述是：【" + pInventory.getItyMatDesc() + "】上传的文件信息如下:<br>文件名：【" + pAnnexModel.getAnxFileName() +
                    "】。<br>文件类型：【" + pAnnexModel.getAnxFileType() + "】。<br>文件大小：【" + pAnnexModel.getAnxFileSize() + "】。<br>上传者IP地址：【" + pAnnexModel.getAnxUploadIp() + "】");
            return "上传成功！";
        }
        return "上传失败！";
    }

    /**
     * @FunctionName: findInventoryList
     * @Description: 外购件出库根据条件查询库存信息
     * @DesignIdea: 外购件出库根据条件查询库存信息
     * @Author: 徐一贺
     * @CreateDate: 2020/5/16 15:39
     * @Phone: 18241927380
     * @Param: [param] 查询条件
     * @Return: com.zhongwang.mms.common.JsonResult
     * @Throw: 无异常抛出
     * @Version: v 1.0.0
     */
    public List<PInventoryModel> findInventoryList(PInventoryModel param) {
        param.setSort(StringUtils.convertFieldToColumn(param.getSort()));
        return purPInventoryDao.findInventoryList(param);
    }


    /**
     * @FunctionName: save
     * @Description: 保存外购件库存要修改的信息
     * @DesignIdea: 保存页面传递来要修改的外购件库存信息
     * @Author: 徐一贺
     * @CreateDate: 2020/5/16 15:41
     * @Phone: 18241927380
     * @Param: [param]
     * @Return: com.zhongwang.mms.common.JsonResult 保存结果
     * @Throw: 无异常抛出
     * @Version: v 1.0.0
     */
    public boolean save(PInventorySavePartialModel param) {
        try {
            if (param.getItyBookkeepingDateText() != null && !param.getItyBookkeepingDateText().equals("")) {
                param.setItyBookkeepingDate(new SimpleDateFormat("yyyy-MM-dd").parse(param.getItyBookkeepingDateText()));
            }
            List<PInventoryModel> beforePInventoryList = purPInventoryDao.findInventoryListByIds(param.getItyIds());
            purPInventoryDao.updateByPrimaryKeysSelective(param);
            List<PInventoryModel> afterPInventoryList = purPInventoryDao.findInventoryListByIds(param.getItyIds());
            Map<String, String> fieldMap = new HashMap<String, String>();
            fieldMap.put("ityProName", "项目名称");
            fieldMap.put("ityPosition", "区位");
            fieldMap.put("ityWhiName", "仓库");
            fieldMap.put("ityBookkeepingDate", "记账日期");
            fieldMap.put("ityRemark", "备注");
            fieldMap.putIfAbsent("ityRemarkType","机械备件库备注类型");
            fieldMap.putIfAbsent("ityCaseNo","箱号");
            for (int i = 0; i < beforePInventoryList.size(); i++) {
                logService.saveLog("【外购件】库存信息编辑", LogFormatUtil.getUpdateResult("编辑的库存信息如下", fieldMap, beforePInventoryList.get(i), afterPInventoryList.get(i)));
            }

        } catch (Exception e) {
            log.error(e.getMessage());
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * @FunctionName: getAnxTable
     * @Description: 获取附件列表
     * @DesignIdea: 根据外购件库存主键获取附件列表
     * @Author: 徐一贺
     * @CreateDate: 2020/5/16 15:40
     * @Phone: 18241927380
     * @Param: [param.anxItyId] 外购件库存主键
     * @Return: com.zhongwang.mms.common.JsonResult 列表地数据
     * @Throw: 无异常抛出
     * @Version: v 1.0.0
     */
    public List<PAnnexModel> findPAnnexModelList(PAnnexModel param) {
        return purAnnexDao.findPAnnexModelList(param);
    }

    /**
     * @FunctionName: getClientIp
     * @Description: 获取客户端IP
     * @DesignIdea: 根据HttpServletRequest请求信息获取客户端IP
     * @Author: 徐一贺
     * @CreateDate: 2020/5/16 15:48
     * @Phone: 18241927380
     * @Param: [request]HttpServletRequest请求信息
     * @Return: [clientIp] 客户端的IP地址
     * @Throw: 无异常抛出
     * @Version: v 1.0.0
     */
    public String getClientIp(HttpServletRequest request) {
        String clientIp = "";
        clientIp = request.getHeader("X-Forwarded-For");
        if (StringUtils.isNotEmpty(clientIp) && !"unKnown".equalsIgnoreCase(clientIp)) {
            //多次反向代理后会有多个ip值，第一个ip才是真实ip
            int index = clientIp.indexOf(",");
            if (index != -1) {
                return clientIp.substring(0, index);
            } else {
                return clientIp;
            }
        }
        clientIp = request.getHeader("X-Real-IP");
        if (StringUtils.isNotEmpty(clientIp) && !"unKnown".equalsIgnoreCase(clientIp)) {
            return clientIp;
        }
        return request.getRemoteAddr();
    }

    /**
     * @FunctionName: download
     * @Description: 文件下载
     * @DesignIdea: 根据外购件附件表主键获取文件信息，进行下载。
     * @Author: 徐一贺
     * @CreateDate: 2020/5/16 15:44
     * @Phone: 18241927380
     * @Param: [anxId, response] 外购件附件表主键、向客户端返回的数据
     * @Return: void
     * @Throw: 无异常抛出
     * @Version: v 1.0.0
     */
    public void download(String anxId, HttpServletResponse response) {
        PAnnexModel pAnnexModel = purAnnexDao.getPAnnexByPrimaryKey(Integer.parseInt(anxId));
        PAnnexModel changePAnnexModel = new PAnnexModel();
        changePAnnexModel.setAnxId(Integer.parseInt(anxId));
        changePAnnexModel.setAnxDownloadCount(pAnnexModel.getAnxDownloadCount() + 1);
        purAnnexDao.updatePAnnexByPrimaryKeySelective(changePAnnexModel);
        PInventoryModel pInventory = purPInventoryDao.getInventoryByPrimaryKey(pAnnexModel.getAnxItyId());
        try {
            XYHFileUtils.download(new File(pAnnexModel.getAnxFilePath()), pAnnexModel.getAnxFileName(), response);
        } catch (IOException e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }
        logService.saveLog("【外购件】库存信息编辑", "下载文件：文件信息如下：<br>" + "【物料描述】：" + pInventory.getItyMatDesc() +
                "。【文件名称】:" + pAnnexModel.getAnxFileName());
    }

    /**
     * @FunctionName: removeFile
     * @Description: 删除文件
     * @DesignIdea: 根据外购件附件表主键删除文件以及附件信息
     * @Author: 徐一贺
     * @CreateDate: 2020/5/16 15:44
     * @Phone: 18241927380
     * @Param: [param.anxId] 外购件附件表主键
     * @Return: void
     * @Throw: 无异常抛出
     * @Version: v 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult removeFile(PAnnexModel param) {
        JsonResult jsonResult = new JsonResult();
        try {
            PAnnexModel pAnnexModel = purAnnexDao.getPAnnexByPrimaryKey(param.getAnxId());
            PInventoryModel pInventory = purPInventoryDao.getInventoryByPrimaryKey(pAnnexModel.getAnxItyId());
            File file = new File(pAnnexModel.getAnxFilePath());
            file.delete();
            purAnnexDao.deletePAnnexByPrimaryKey(param.getAnxId());
            logService.saveLog("【外购件】库存信息编辑", "删除文件：文件信息如下：<br>" + "【物料描述】：" + pInventory.getItyMatDesc() +
                    "。【文件名称】:" + pAnnexModel.getAnxFileName());
            jsonResult.setType(JsonResult.ResultType.SUCCESS);
            jsonResult.setMsg("删除文件成功！");
            if (purAnnexDao.findPAnnexModelList(param).size() == 0) {
                PInventory changePInventoryAnnexFlagModel = new PInventory();
                changePInventoryAnnexFlagModel.setItyId(pAnnexModel.getAnxItyId());
                changePInventoryAnnexFlagModel.setItyAnnexFlag(0);
                purPInventoryDao.updateByPrimaryKeySelective(changePInventoryAnnexFlagModel);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("删除文件失败！");
        }
        return jsonResult;
    }

    /**
     * @FunctionName: findPInventoryMaterielInfoList
     * @Description: 加载台账管理列表
     * @DesignIdea: 加载台账管理列表
     * @Author: 徐一贺
     * @CreateDate: 2020/5/27 15:09
     * @Phone: 18241927380
     * @Param: [param] 查询参数
     * @Return: com.zhongwang.mms.common.JsonResult 结果
     * @Throw: 无异常抛出
     * @Version: 1.0.0
     */
    public List<PInventoryMaterielInfoModel> findPInventoryMaterielInfoList(PInventoryMaterielInfoModel param) {
        param.setImiStatus(1);
        return purPInventoryMaterielInfoDao.findPInventoryMaterielInfoBySelective(param);
    }

    /**
     * @FunctionName: addLedger
     * @Description: 保存台账
     * @Author: 徐一贺
     * @CreateDate: 2020/5/27 16:42
     * @Phone: 18241927380
     * @Param: [param] 台账信息
     * @Return: com.zhongwang.mms.common.JsonResult
     * @Version: v1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult saveLedger(PInventoryMaterielInfoModel param) {
        JsonResult jsonResult = new JsonResult();
        try {
            if (param.getImiId() == null) {
                param.setImiStatus(1);
                PInventory pInventory = new PInventory();
                pInventory.setItyId(param.getImiItyId());
                pInventory.setItyMaterielInfoFlag(1);
                purPInventoryDao.updateByPrimaryKeySelective(pInventory);
                purPInventoryMaterielInfoDao.insertSelective(param);
                //logService.saveLog("【外购件库】新增台账", "新增的台账字段名是：" + param.getImiField());
                Map<String, String> fieldMap = new HashMap<String, String>();
                fieldMap.put("imiField", "字段名");
                fieldMap.put("imiValue", "台账值");
                fieldMap.put("imiUnit", "单位");
                logService.saveLog("【外购件库】新增台账", LogFormatUtil.getInsertResult("物料描述为" + purPInventoryDao.getInventoryByPrimaryKey(param.getImiItyId()).getItyMatDesc() + "的库存信息新增的台账信息如下", fieldMap, param));
            } else {
                PInventoryMaterielInfoModel before = purPInventoryMaterielInfoDao.getPInventoryMaterielInfoModelByPrimaryKey(param.getImiId());
                purPInventoryMaterielInfoDao.updateSelective(param);
                PInventoryMaterielInfoModel after = purPInventoryMaterielInfoDao.getPInventoryMaterielInfoModelByPrimaryKey(param.getImiId());
                logService.saveLog("【外购件库】修改台账", "台账字段名：" + before.getImiField() + "==>" + after.getImiField() + "<br>" +
                        "台账值：" + before.getImiValue() + "==>" + after.getImiValue() + "<br>" +
                        "台账单位：" + before.getImiUnit() + "==>" + after.getImiUnit());
            }
            jsonResult.setType(JsonResult.ResultType.SUCCESS);
            jsonResult.setMsg("保存成功！");
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("添加失败！");
        }
        return jsonResult;
    }

    /**
     * @FunctionName: removeLedger
     * @Description: 删除台账信息
     * @DesignIdea: 根据主键删除台账信息
     * @Author: 徐一贺
     * @CreateDate: 2020/5/28 8:28
     * @Phone: 18241927380
     * @Param: [param.imiId] 台账主键
     * @Return: com.zhongwang.mms.common.JsonResult 结果
     * @Version: v1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult removeLedger(PInventoryMaterielInfoModel param) {
        JsonResult jsonResult = new JsonResult();
        try {
            PInventoryMaterielInfoModel pInventoryMaterielInfoModel = purPInventoryMaterielInfoDao.getPInventoryMaterielInfoModelByPrimaryKey(param.getImiId());
            param.setImiStatus(0);
            purPInventoryMaterielInfoDao.updateSelective(param);
            Integer count = purPInventoryMaterielInfoDao.findPInventoryMaterielInfoCountByimiItyIdAndImiStatus(param.getImiItyId());
            if (count == 0) {
                PInventory pInventory = new PInventory();
                pInventory.setItyId(param.getImiItyId());
                pInventory.setItyMaterielInfoFlag(0);
                purPInventoryDao.updateByPrimaryKeySelective(pInventory);
            }
            jsonResult.setType(JsonResult.ResultType.SUCCESS);
            jsonResult.setMsg("删除成功！");
            logService.saveLog("【外购件库】删除台账", "删除的台账字段名是：" + pInventoryMaterielInfoModel.getImiField());
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("删除失败！");
        }
        return jsonResult;
    }

    /**
     * @FunctionName: getLedger
     * @Description: 获取台账信息
     * @DesignIdea: 根据主键获取台账信息
     * @Author: 徐一贺
     * @CreateDate: 2020/5/28 8:28
     * @Phone: 18241927380
     * @Param: [param.imiId] 台账主键
     * @Return: com.zhongwang.mms.common.JsonResult 结果
     * @Version: v1.0.0
     */
    public JsonResult getLedger(PInventoryMaterielInfoModel param) {
        JsonResult jsonResult = new JsonResult();
        try {
            PInventoryMaterielInfoModel pInventoryMaterielInfoModel = purPInventoryMaterielInfoDao.getPInventoryMaterielInfoModelByPrimaryKey(param.getImiId());
            jsonResult.setType(JsonResult.ResultType.SUCCESS);
            jsonResult.setData(pInventoryMaterielInfoModel);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
        }
        return jsonResult;
    }

    /**
     * @FunctionName: getPInventoryList
     * @Description: 获取库存信息列表
     * @DesignIdea: 获取库存信息列表
     * @Author: 徐一贺
     * @CreateDate: 2020年7月11日10:12:28
     * @Phone: 18241927380
     * @Param: [param.imiId] 台账主键
     * @Return: com.zhongwang.mms.common.JsonResult 结果
     * @Version: v1.0.0
     */
    public List<PInventoryModel> getPInventoryList(PInventoryModel param) {
        return purPInventoryDao.findInventoryListByIds(param.getItyIds());
    }
}